﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace PickGold
{
	/// <summary>
	/// 可空逻辑值类型
	/// </summary>
	[Serializable]
	[DataContract]
	[ComVisible(true)]
	[DebuggerDisplay("{Value}")]
	[ClassInterface(ClassInterfaceType.AutoDispatch)]
	public sealed class NullableBoolean
	{
		/// <summary>
		/// 真值
		/// </summary>
		public readonly static NullableBoolean True = new NullableBoolean(true);
		/// <summary>
		/// 假值
		/// </summary>
		public readonly static NullableBoolean False = new NullableBoolean(false);

		/// <summary>
		/// 实例化
		/// </summary>
		public NullableBoolean()
		{
			this.Value = false;
		}

		/// <summary>
		/// 实例化
		/// </summary>
		/// <param name="value">值</param>
		public NullableBoolean(bool value)
		{
			this.Value = value;
		}

		/// <summary>
		/// 实例化
		/// </summary>
		/// <param name="value">值</param>
		public NullableBoolean(decimal value)
		{
			if (value == decimal.Zero)
				this.Value = false;
			else
				this.Value = true;
		}

		/// <summary>
		/// 实例化
		/// </summary>
		/// <param name="value">值</param>
		public NullableBoolean(string value)
		{
			this.Value = value.ToBoolean();
		}

		/// <summary>
		/// 值
		/// </summary>
		public bool Value { set; get; }

		/// <summary>
		/// 返回一个值，该值指示此实例是否与指定的对象相等。
		/// </summary>
		/// <param name="obj">要与此实例进行比较的对象。</param>
		/// <returns>如果 obj 为 System.Boolean 并与此实例的值相等，则为 true；否则为 false。</returns>
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			var nb = obj as NullableBoolean;
			if (nb == null)
				return false;

			return this.Value.Equals(nb.Value);
		}

		/// <summary>
		/// 返回此实例的哈希代码。
		/// </summary>
		/// <returns>当前 System.Boolean 的哈希代码。</returns>
		public override int GetHashCode()
		{
			return this.Value.GetHashCode();
		}

		/// <summary>
		/// 将此实例的值转换为其等效的字符串表示。
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			return this.Value.ToString();
		}

		/// <summary>
		/// 隐式转换
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static implicit operator bool(NullableBoolean value)
		{
			return value != null && value.Value;
		}

		/// <summary>
		/// 隐式转换
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static implicit operator Nullable<bool>(NullableBoolean value)
		{
			if (value == null)
				return null;

			return new Nullable<bool>(value != null && value.Value);
		}

		/// <summary>
		/// 显式转换
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static explicit operator NullableBoolean(bool value)
		{
			return new NullableBoolean(value);
		}

		/// <summary>
		/// 显式转换
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static explicit operator NullableBoolean(Nullable<bool> value)
		{
			if (value == null)
				return null;

			return new NullableBoolean(value.Value);
		}

		/// <summary>
		/// 真值判断
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static bool operator true(NullableBoolean value)
		{
			return NullableBoolean.IsTrue(value);
		}

		/// <summary>
		/// 假值判断
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static bool operator false(NullableBoolean value)
		{
			return NullableBoolean.IsFalse(value);
		}
		/*
		public static NullableBoolean operator !(NullableBoolean r)
		{
			if (r == null)
				return null;

			if (r.Value)
				return new NullableBoolean(false);//return false;//

			return new NullableBoolean(true);
		}
		
		public static bool operator ==(NullableBoolean l, NullableBoolean r)
		{
			return NullableBoolean.Equals(l, r);
		}

		public static bool operator ==(bool l, NullableBoolean r)
		{
			return NullableBoolean.Equals(r, l);
		}

		public static bool operator ==(Nullable<bool> l, NullableBoolean r)
		{
			return NullableBoolean.Equals(r, l);
		}

		public static bool operator ==(NullableBoolean l, bool r)
		{
			return NullableBoolean.Equals(r, l);
		}

		public static bool operator ==(NullableBoolean l, Nullable<bool> r)
		{
			return NullableBoolean.Equals(r, l);
		}

		public static bool operator !=(NullableBoolean l, NullableBoolean r)
		{
			return !NullableBoolean.Equals(l, r);
		}

		public static bool operator !=(bool l, NullableBoolean r)
		{
			return !NullableBoolean.Equals(r, l);
		}

		public static bool operator !=(Nullable<bool> l, NullableBoolean r)
		{
			return !NullableBoolean.Equals(r, l);
		}

		public static bool operator !=(NullableBoolean l, bool r)
		{
			return !NullableBoolean.Equals(l, r);
		}

		public static bool operator !=(NullableBoolean l, Nullable<bool> r)
		{
			return !NullableBoolean.Equals(l, r);
		}
		*/
		/// <summary>
		/// 真值判断
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static bool IsTrue(NullableBoolean value)
		{
			return value != null && value.Value;
		}

		/// <summary>
		/// 假值判断
		/// </summary>
		/// <param name="value">值</param>
		/// <returns>值</returns>
		public static bool IsFalse(NullableBoolean value)
		{
			return value == null || !value.Value;
		}

		/// <summary>
		/// 等值判断
		/// </summary>
		/// <param name="this">左值</param>
		/// <param name="value">右值</param>
		/// <returns>值</returns>
		public static bool Equals(NullableBoolean @this, bool value)
		{
			if (@this == null)
				return false;

			if (@this.Value == value)
				return true;

			return false;
		}

		/// <summary>
		/// 等值判断
		/// </summary>
		/// <param name="this">左值</param>
		/// <param name="value">右值</param>
		/// <returns>值</returns>
		public static bool Equals(NullableBoolean @this, Nullable<bool> value)
		{
			if (@this == null && value == null)
				return true;

			if (@this == null)
				return false;

			if (value == null)
				return false;

			if (@this.Value == value.Value)
				return true;

			return false;
		}

		/// <summary>
		/// 等值判断
		/// </summary>
		/// <param name="this">左值</param>
		/// <param name="value">右值</param>
		/// <returns>值</returns>
		public static bool Equals(NullableBoolean @this, NullableBoolean value)
		{
			if (@this == null && value == null)
				return true;

			if (@this == null)
				return false;

			if (value == null)
				return false;

			if (@this.Value == value.Value)
				return true;

			return false;
		}
	}
}
